// interface Config {
//     age:number;
//     name:string;
//     isActive:boolean;
//     like:string; // 可选属性
// }

// const config: Config = {
//     age: 30,
//     name: "John Doe",
//     isActive: true,
//     like: "test" // 额外属性
// };
// // 部分可选


// // 将name age 可选

// type Keys = keyof Config;

// type PartialKey = 'name' | 'age' | 'like';


// // 将K 的属性变为可选
// type PartialNameUser<T,K extends keyof T> = Partial<Pick<T,K>> &Omit<T,K>
// const user: PartialNameUser<Config,PartialKey> = {
//     // name: "Jane Doe",
//     // age: 25,
//     isActive: true
// };

// interface Config {
//   id: number;
//   name: string;
//   age: number;
//   status: boolean;
// }
// // 将部分 属性变为 readonly
// type ReadonlyKeys = 'id' | 'name';

// type Readonly1<T,K extends keyof T> = Readonly<Pick<T,K>> & Omit<T,K>;
// const user: Readonly1<Config,ReadonlyKeys> = {
//   id: 1,
//   name: "Jane Doe",
//   age: 25,
//   status: true
// };

// user.id = 2; // 错误，id 是只读属性
// user.name = "John Smith"; // 错误，name 是只读属性
// user.age = 30; // 正确，age 不是只读属性
// user.status = false; // 正确，status 不是只读属性

// 让类型 T 中 K 指定的字段变为可选

interface Config {
  id?: number;
  name: string;
  age: number;
  status?: boolean;
}
// type PartiallyOptional<T, K extends keyof T> = Partial<Pick<T,K>> & Omit<T, K>;
// // name 可选
// const user: PartiallyOptional<Config, 'name'> = {
//   id: 1,
//   status: true,
//   name: "Jane Doe", // 可选
//   age: 25 // 可选
// };

// type PartiallyReadonly<T, K extends keyof T> = Readonly<Pick<T,K>> & Omit<T, K>;
// const user: PartiallyReadonly<Config, 'id' | 'age'> = {
//   id: 1,
//   status: true,
//   name: "Jane Doe", // 只读
//   age: 25 // 可选
// };
// user.name = "Jane Doe";     
// user.age = 2; 
// user.id = 2; 
// user.status = false; 

// 让 T 中 K 指定的字段变成必填 Required !!!
type RequiredByKeys<T, K extends keyof T> = Required<Pick<T,K>> & Omit<T, K>;
const u: RequiredByKeys<Config, 'status' | 'name'> = {
  id: 1,
  name: "Jane Doe",
  age: 25,
  status: true,
};

// Merge 两个类型 如果有同名字段，以 U 为准
type Merge<T, U> = Omit<T,keyof U> & U
type T1 = { id: number; name: string }
type T2 = { name: boolean; age: number }

const merged: Merge<T1, T2> = {
  id: 1,
  name: true, // T2 中的 name 覆盖了 T1 中的 name
  age: 30
};

// 实现一个工具类型，把类型 T 中所有的只读属性变为可写：
type Mutable<T> = {
  -readonly [P in keyof T]
}
// type Foo = {
//   readonly a: number;
//   readonly b: string;
//   c: boolean;
// }
// type Bar = Mutable<Foo>

// 实现：筛选出 T 中值类型是 U 的字段
type FilterByValueType<T, U> = {
  [K in keyof T as T[K] extends U ? K : never]: T[K]
}
type Foo = { a: string; b: number; c: boolean; d: number }
type R = FilterByValueType<Foo, number>
// { b: number; d: number }